package com.imooc.web.async;

import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.RandomStringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.async.DeferredResult;

import java.util.concurrent.Callable;

/**
 * Created by zghgchao 2018/4/19 20:21
 */
@RestController
public class AsyncController {
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @RequestMapping("/order")
    @ApiOperation(value = "同步执行方式")
    public String order() throws Exception{
        logger.info("主线程开始");
        Thread.sleep(1000);//当作下单执行逻辑
        logger.info("主线程返回");
        return "success";
    }


    @RequestMapping("/order1")
    @ApiOperation(value = "callable方式执行方式")
    public Callable<String> order1() throws Exception{
        logger.info("主线程开始");
        Callable<String> result = () -> {  //callable方式：（缺点）线程必须放在主线程里
            logger.info("副线程开始执行");
            Thread.sleep(1000);//当作下单执行逻辑
            logger.info("副线程开始返回");
            return "success";
        };
        logger.info("主线程返回");
        return result;
    }

    @Autowired
    private MockQueue mockQueue;

    @Autowired
    private DeferreResultHolder deferreResultHolder;


    @RequestMapping("/order2")
    @ApiOperation(value = "DeferreResult方式执行方式")
    public DeferredResult<String> order2() throws Exception{
        logger.info("主线程开始");
        String orderNumber = RandomStringUtils.randomNumeric(8);//生成8位的随机数
        mockQueue.setPlaceOrder(orderNumber);

        DeferredResult<String> result = new DeferredResult<>();

        deferreResultHolder.getMap().put(orderNumber,result);//放一个空的result，监听到订单后将处理后的结果放到result中

        logger.info("主线程返回");
        return result;
    }
}
